package org.dromara.common.web.config;

import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.jsr.WebSocketDeploymentInfo;
import org.dromara.common.core.utils.SpringUtils;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.web.embedded.undertow.UndertowServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.core.task.VirtualThreadTaskExecutor;


/**
 * @Author 刘武贵
 * @Date 2024/8/15 22:00
 * @Description 功能描述：Undertow 自定义配置
 */
/**
 * Undertow配置类，用于定制UndertowServletWebServerFactory的配置
 * 该类实现了WebServerFactoryCustomizer接口，针对Undertow web服务器提供了定制化配置的能力
 */
@AutoConfiguration
public class UndertowConfig implements WebServerFactoryCustomizer<UndertowServletWebServerFactory> {

    /**
     * 自定义Undertow的配置
     * 在此方法中，我们可以添加额外的部署信息定制器，以初始化WebSocket服务的配置信息
     * 以及根据需要设置线程池执行器
     *
     * @param factory UndertowServletWebServerFactory实例，用于配置Web应用程序的服务器工厂
     */
    @Override
    public void customize(UndertowServletWebServerFactory factory) {
        // 添加部署信息定制器，用于配置WebSocket服务的缓冲区和执行器
        factory.addDeploymentInfoCustomizers(deploymentInfo -> {
            // 初始化WebSocket部署信息
            WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
            // 设置WebSocket的缓冲区为一个直接缓冲区，大小为1024字节
            webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(true, 1024));
            // 将WebSocket部署信息作为上下文属性添加到部署信息中
            deploymentInfo.addServletContextAttribute("io.undertow.websockets.jsr.WebSocketDeploymentInfo", webSocketDeploymentInfo);
            // 使用虚拟线程 如果当前使用的是虚拟线程，则配置虚拟线程执行器
            if (SpringUtils.isVirtual()) {
                // 创建一个虚拟线程执行器，用于处理WebSocket的异步任务
                VirtualThreadTaskExecutor executor = new VirtualThreadTaskExecutor("undertow-");
                // 设置部署信息的执行器为虚拟线程执行器
                deploymentInfo.setExecutor(executor);
                // 设置部署信息的异步执行器为虚拟线程执行器
                deploymentInfo.setAsyncExecutor(executor);
            }
        });
    }

}
